"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBasicAuthToken = createBasicAuthToken;
const tslib_1 = require("tslib");
/**不安全网络请求操作类 */
const Http = tslib_1.__importStar(require("http"));
/**安全网络请求操作类 */
const Https = tslib_1.__importStar(require("https"));
/**base64处理 */
const m_b64_1 = tslib_1.__importDefault(require("./m-b64"));
/**创建基础验证数据 */
function createBasicAuthToken(auth) {
    const { user, pass } = auth;
    const token = user + ":" + pass;
    const hash = m_b64_1.default.encode(token); // Base64 编码
    return "Basic " + hash;
}
/**网络请求 */
class MHttp {
    /**基础配置 */
    static defaults = {};
    /**获取当前网络请求器 */
    static getRequester(config) {
        const { base, url } = config;
        const res = url instanceof URL ? new URL(url) : new URL(url || "", base);
        if (base)
            res.host = base;
        return res.protocol === "https:" ? Https : Http;
    }
    /**获取请求url */
    static getUrl(config) {
        const { base, url } = config;
        const parms = config.pararms || {};
        const res = url instanceof URL ? new URL(url) : new URL(url || "", base);
        if (base)
            res.host = base;
        const search = res.search || "";
        const path = decodeURIComponent(res.pathname || "");
        for (const p in parms) {
            const hasKey = new RegExp(`{${p}}`, "i");
            path.replace(new RegExp(`{${p}}`, "gi"), `${parms[p]}`);
            if (hasKey)
                delete parms[p];
        }
        res.pathname = path;
        let query = "";
        for (const p in parms)
            query = `${query}&${p}=${parms[p]}`;
        res.search = search.includes("?")
            ? `${search}${query}`
            : `?${query.replace(/^&+/, "")}`;
        return new URL(res);
    }
    /**合并请求头 */
    static mergeHeaders(config) {
        const { defaults } = MHttp;
        const headers = Object.assign({}, defaults.headers, config.headers);
        if (headers["Authorization"])
            return headers;
        const baseAuth = Object.assign({}, defaults.baseAuth, config.baseAuth);
        if (baseAuth.user && baseAuth.pass) {
            headers["Authorization"] = createBasicAuthToken(baseAuth);
        }
        return headers;
    }
    /**合并氢气配置 */
    static mergeConfig(config) {
        const { defaults } = MHttp;
        const res = Object.assign({}, defaults, config);
        res.headers = MHttp.mergeHeaders(config);
        return res;
    }
    /**获取请求配置 */
    static getOptions(config) {
        const { method, headers, timeout } = config;
        const url = MHttp.getUrl(config);
        return {
            method: method || "GET",
            protocol: url.protocol,
            host: url.hostname,
            port: url.port,
            path: `${url.pathname}${url.search}`,
            headers,
            timeout,
        };
    }
    /**GET请求 */
    static async get(url, parm, config) {
        const pararms = parm || {};
        const c = { ...(config || {}), url, pararms };
        return MHttp.request(c);
    }
    /**POST请求 */
    static async post(url, data, config) {
        const c = { ...(config || {}), url, data };
        return MHttp.request(c);
    }
    /**PUT请求 */
    static async put(url, data, config) {
        const c = { ...(config || {}), url, data };
        return MHttp.request(c);
    }
    /**DELETE请求 */
    static async delete(url, parm, config) {
        const pararms = parm || {};
        const c = { ...(config || {}), url, pararms };
        return MHttp.request(c);
    }
    /**发起请求 */
    static async request(config) {
        return new Promise((resolve, reject) => {
            const conf = MHttp.mergeConfig(config);
            const requester = MHttp.getRequester(conf);
            const options = MHttp.getOptions(conf);
            const req = requester.request(options, (res) => {
                let data = "";
                res.setEncoding("utf8");
                res.on("data", (chunk) => (data += chunk));
                res.on("end", () => resolve(MHttp.getResponse(res, data)));
            });
            req.on("error", (evt) => reject(evt));
            if (config.data)
                req.write(config.data);
            req.end();
        });
    }
    /**解析返回结果 */
    static getResponse(res, body = "") {
        const headers = res.headers || {};
        const status = res.statusCode || 0;
        const serverType = headers["content-type"] ||
            headers["Content-type"] ||
            headers["content-Type"] ||
            headers["Content-Type"] ||
            "";
        const type = serverType instanceof Array ? serverType.join(";") : serverType;
        body = /application\/json/i.test(type) ? JSON.parse(body) : body;
        const data = body || "";
        return { status, headers, data };
    }
}
exports.default = MHttp;
